package search

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"path"

	"gitee.com/Flearning/go_crawl/modules"
	"gitee.com/Flearning/go_crawl/setting"
	"gitee.com/Flearning/go_crawl/utils"

	"gopkg.in/go-module/log.v1"
	"gopkg.in/mgo.v2/bson"
)

type myScheduler struct {
	uriPath string
	prames  *modules.XueQiuPrames
	reqCI   *modules.ReqCrawlInfo
}

var ReqCfg *modules.ReqCrawlInfo

// NewScheduler 会创建一个调度器实例。
func NewScheduler() *myScheduler {
	return &myScheduler{}
}

func (sched *myScheduler) Init(prames *modules.XueQiuPrames) *myScheduler {
	sched.reqCI = ReqCfg
	sched.prames = prames
	sched.uriPath = fmt.Sprintf(sched.reqCI.Url, prames.Symbol, prames.Source, prames.Page, prames.Sort)
	return sched
}

func (sched *myScheduler) Start() (int, []byte) {
	log.Info("Currently Crawl Data URL: %v", sched.uriPath)
	return sched.reqCI.HttpNewRequest(sched.uriPath)
}

func (sched *myScheduler) Run(statusCode int, respBodyBtye []byte) []ListStruct {
	if statusCode != http.StatusOK {
		err := fmt.Errorf("this crawl data statusCode: %d", statusCode)
		log.Info("Currently Crawl Data Page Num:%d", sched.prames.Page)
		log.Error(4, "the crawl data fail: %v", err)
		return nil
	}
	j2s := new(BodyJsonFormat)
	json.Unmarshal(respBodyBtye, j2s)
	bsonD := j2s.BsonData(respBodyBtye)
	if sched.prames.Page <= j2s.MaxPage {
		sched.prames.Page = sched.prames.Page + 1
		sched.uriPath = fmt.Sprintf(sched.reqCI.Url, sched.prames.Symbol, sched.prames.Source, sched.prames.Page, sched.prames.Sort)
	}
	return bsonD
}

func (sched *myScheduler) HandleData(bsonD ...ListStruct) bool {
	var sign bool
	l := len(bsonD)
	log.Info("len bsonD %v", l)
	if l == 0 {
		return sign
	}
	newRes := make([]interface{}, 0)
	newBsonD := make([]ListStruct, 0)
	for i := 0; i < l; i++ {
		where := make([]bson.M, 0)
		where = []bson.M{
			bson.M{"created_at": bsonD[i].CreatedAt},
			bson.M{"source_": bsonD[i].Source_},
		}
		ck, _ := RunXueqiuCheck(where)
		if !ck {
			newRes = append(newRes, bsonD[i])
			newBsonD = append(newBsonD, bsonD[i])
		}
	}
	n := len(newRes)
	log.Info("len newRes %v", n)
	if n < l && n == 0 {
		sign = true
	}

	if n > 0 {
		RunXueqiuInstert(newRes...)
		RunStripDataInstert(newBsonD...)
	}
	return sign
}

func (sched *myScheduler) GetName(key string) {
	fmt.Println(key, sched.uriPath)
}

func ReadCrawlInfo() ([]byte, error) {
	siteinfos := setting.Sites
	crawlInfoLen := len(siteinfos)
	log.Info("Crawl Site Config Count: %d", crawlInfoLen)

	pwd, _ := utils.WorkDir()
	cfgPath := path.Join(pwd, "conf", siteinfos[0])

	ckFile := utils.IsFile(cfgPath)

	if ckFile {
		rb, err := ioutil.ReadFile(cfgPath)
		if err != nil {
			log.Error(4, "ReadFile config `./conf/%s` Error: %v", siteinfos[0], err)
			return nil, err
		}
		return rb, err
	} else {
		err := fmt.Errorf("Can not Read config `./conf/%s`", siteinfos[0])
		log.Error(4, "Can not Read config `./conf/%s", siteinfos[0])
		return nil, err
	}
}

func (r *BodyJsonFormat) BsonData(rb []byte) []ListStruct {
	rbf := new(BodyJsonFormat)
	json.Unmarshal(rb, rbf)
	bsonD := make([]ListStruct, 0)
	json.Unmarshal(*rbf.List, &bsonD)
	//	bsonI := make([]interface{}, 0)
	//	for _, val := range bsonD {
	//		bsonI = append(bsonI, val)
	//	}
	//	return bsonI
	return bsonD
}
